package com.j4dream.property.Initializer;

import com.google.common.collect.Sets;
import com.j4dream.property.dao.*;
import com.j4dream.property.model.PermissionDto;
import com.j4dream.property.model.RoleDto;
import com.j4dream.property.model.UserDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
public class UserInitializer implements InitializingBean {

    @Value("${administrator.email}")
    private String email;
    @Value("${administrator.name}")
    private String name;
    @Value("${administrator.first-name}")
    private String firstName;
    @Value("${administrator.last-name}")
    private String lastName;
    @Value("${administrator.password}")
    private String password;

    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private GeoDao geoDao;

    @Override
    public void afterPropertiesSet() throws Exception {
        List<UserDto> userDtoList = userDao.getUserList();
        List<PermissionDto> permissionDtoList = permissionDao.getPermList();
        Set<String> existPerms = permissionDtoList.stream().map(PermissionDto::getName).collect(Collectors.toSet());
        Set<String> allPerms = RoleConsts.ADMIN;
        Sets.SetView<String> newAddSet = Sets.difference(allPerms, existPerms);
        List<PermissionDto> newPermissonDtoList = newAddSet.stream()
                .map(s -> addPerm(s, ""))
                .collect(Collectors.toList());

        permissionDtoList.addAll(newPermissonDtoList);

        List<RoleDto> roleDtoList = roleDao.getRoleList();
        RoleDto adminRole = roleDtoList.stream()
                .filter(r -> "ADMIN".equals(r.getName()))
                .findAny()
                .orElse(null);

        List<Integer> permIds;
        if (adminRole == null) {
            adminRole = addRole("ADMIN");
            permIds = permissionDtoList.stream().map(PermissionDto::getId).collect(Collectors.toList());
            roleDao.grantPermission(adminRole.getId(), permIds);
        }


        if (null == userDtoList || userDtoList.isEmpty()) {
            log.info("Init admin user.");
            UserDto userDto = new UserDto();
            userDto.setEmail(email);
            userDto.setPassword(password);
            userDto.setName(name);
            userDto.setFirstName(firstName);
            userDto.setLastName(lastName);
            userDto.setCreateTime(new Date().getTime());
            userDao.insertUser(userDto);
        }
        log.info("Ingore Init administrator.");

        if(geoDao.getGeosByPkey("86").size() == 0) {
            log.info("Init geographic");
            List<GeoDto> list = Geographic.getAllGeos();
            for(GeoDto g : list) {
                geoDao.insert(g);
            }
        }

    }

    private PermissionDto addPerm(String name, String desc) {
        PermissionDto permissionDto = new PermissionDto(name, desc);
        permissionDao.insertPermission(permissionDto);
        return permissionDto;
    }

    private RoleDto addRole(String name) {
        RoleDto roleDto = new RoleDto(name);
        roleDao.insertRole(roleDto);
        return roleDto;
    }
}
